/**
 *  @(#)  IFAAAuthenticator  module    1.0  2017/03/24
 *
 *  Copyright  (c)  2017,  IFAA  and/or  its  affiliates.  All  rights  reserved.
 *
 *  Redistribution  and  use  in  source  and  binary  forms,  with  or  without
 *  modification,  are  permitted  provided  that  the  following  conditions  are  met:
 *
 *  -Redistribution  of  source  code  must  retain  the  above  copyright  notice,  this
 *    list  of  conditions  and  the  following  disclaimer.
 *
 *  -Redistribution  in  binary  form  must  reproduce  the  above  copyright  notice,
 *    this  list  of  conditions  and  the  following  disclaimer  in  the  documentation
 *    and/or  other  materials  provided  with  the  distribution.
 *
 *  Neither  the  name  of  IFAA  or  the  names  of  contributors  may
 *  be  used  to  endorse  or  promote  products  derived  from  this  software  without
 *  specific  prior  written  permission.
 *
 *  This  software  is  provided  "AS  IS,"  without  a  warranty  of  any  kind.  ALL
 *  EXPRESS  OR  IMPLIED  CONDITIONS,  REPRESENTATIONS  AND  WARRANTIES,  INCLUDING
 *  ANY  IMPLIED  WARRANTY  OF  MERCHANTABILITY,  FITNESS  FOR  A  PARTICULAR  PURPOSE
 *  OR  NON-INFRINGEMENT,  ARE  HEREBY  EXCLUDED.  IFAA,  ORG.
 *  AND  ITS  LICENSORS  SHALL  NOT  BE  LIABLE  FOR  ANY  DAMAGES  SUFFERED  BY  LICENSEE
 *  AS  A  RESULT  OF  USING,  MODIFYING  OR  DISTRIBUTING  THIS  SOFTWARE  OR  ITS
 *  DERIVATIVES.  IN  NO  EVENT  WILL  IFAA  OR  ITS  LICENSORS  BE  LIABLE  FOR  ANY  LOST
 *  REVENUE,  PROFIT  OR  DATA,  OR  FOR  DIRECT,  INDIRECT,  SPECIAL,  CONSEQUENTIAL,
 *  INCIDENTAL  OR  PUNITIVE  DAMAGES,  HOWEVER  CAUSED  AND  REGARDLESS  OF  THE  THEORY
 *  OF  LIABILITY,  ARISING  OUT  OF  THE  USE  OF  OR  INABILITY  TO  USE  THIS  SOFTWARE,
 *  EVEN  IF  IFAA  HAS  BEEN  ADVISED  OF  THE  POSSIBILITY  OF  SUCH  DAMAGES.
 *
 *  You  acknowledge  that  this  software  is  not  designed,  licensed  or  intended
 *  for  use  in  the  design,  construction,  operation  or  maintenance  of  any
 *  nuclear  facility.
 *
 */
package com.ifaa.sdk.authenticatorservice.fingerprint.util;

import org.ifaa.ifaf.Extension;
import org.ifaa.ifaf.OperationHeader;
import org.ifaa.ifaf.enums.EnumIfaaOperationType;
import org.ifaa.ifaf.message.IFAFMessage;
import org.ifaa.ifaf.message.IFAFSignedData;

import android.os.Bundle;
import android.util.Base64;

import com.ifaa.sdk.util.ByteUtils;
import com.ifaa.sdk.authenticatorservice.message.Result;
import com.ifaa.sdk.auth.message.AuthenticatorMessage;
import com.ifaa.sdk.auth.message.AuthenticatorResponse;
import com.google.gson.Gson;

/**
 * 
 * @author qiyi.wxc
 * @version 1.0
 */
public class FingerprintDataUtil {

    public static final String KEY_APPNAME = "appname";
    public static String appname;

    /**
     * bundle
     * @param operation
     * @param resultCode
     * @return
     */
    public static Bundle constructResultBundle(int operation, int resultCode) {
        return constructResultBundle(operation, resultCode, null);
    }

    public static Bundle constructResultBundle(int operation, int resultCode, int errCode) {
        Bundle bundle = new Bundle();
        bundle.putInt(AuthenticatorMessage.KEY_OPERATIONT_TYPE, operation);
        bundle.putInt(AuthenticatorMessage.KEY_RESULT, resultCode);
        bundle.putInt(AuthenticatorMessage.KEY_ERROR_CODE, errCode);
        bundle.putString(AuthenticatorMessage.KEY_ERROR_STRING, Result.getStatusStringIFAA2(errCode));

        return bundle;
    }
    /**
     * bundle
     * @param operation
     * @param resultCode
     * @return
     */
    public static Bundle constructResultBundle(int operation, int resultCode, String message) {
        Bundle bundle = new Bundle();
        bundle.putInt(AuthenticatorMessage.KEY_OPERATIONT_TYPE, operation);
        bundle.putInt(AuthenticatorMessage.KEY_RESULT, resultCode);

        if (message != null && message.length() != 0) {
            bundle.putString(AuthenticatorMessage.KEY_MESSAGE, message);
        }

        return bundle;
    }

    /**
     * build Result from TEEData
     * 
     * @param resultData
     * @return
     */
    public static Result buildResult(byte[] resultData) {
        if (resultData == null) {
            return new Result(AuthenticatorResponse.RESULT_TEE_INVOKE_RETURN_NULL, null);
        }

        byte[] data = new byte[resultData.length - 8];

        ByteUtils.copy(resultData, 8, resultData.length - 8, data, 0);
        Result result = new Result();

        result.setStatus(ByteUtils.toInt(resultData));

        result.setData(data);
        return result;
    }

    /**
     * make Regist Response using given date
     * 
     * @param operationHeader
     * @param result
     * @return
     */
    public static String makeRegResponse(String aaid, OperationHeader operationHeader, Result result) {
        operationHeader.setOpType(EnumIfaaOperationType.RESPONSE.getValue());
        operationHeader.setDeviceModel(aaid);
        IFAFMessage registerResponse = new IFAFMessage();
        registerResponse.setHeader(operationHeader);

        if (!appname.isEmpty()) {
            Extension[] extensions = new Extension[1];
            Extension extension = new Extension();
            extension.setId(KEY_APPNAME);
            extension.setData(appname);
            extensions[0] = extension;
            registerResponse.setExts(extensions);
        }

        byte[] krd = new byte[result.getData().length];
        ByteUtils.copy(result.getData(), 0, result.getData().length, krd, 0);

        IFAFSignedData signedData = new IFAFSignedData();
        signedData.setScheme("IFAFV1TLV");
        signedData.setIdentifyData(Base64.encodeToString(krd, Base64.URL_SAFE));

        registerResponse.setSignedData(signedData);

        Gson gson = new Gson();
        String registerMessage = gson.toJson(registerResponse);
        return registerMessage;
    }

    /**
     * make Authenticate Response using given date
     * 
     * @param operationHeader
     * @param result
     * @return
     */
    public static String makeAuthResponse(String aaid, OperationHeader operationHeader,
                                          Result result) {
        operationHeader.setOpType(EnumIfaaOperationType.RESPONSE.getValue());
        operationHeader.setDeviceModel(aaid);
        IFAFMessage authenticationResponse = new IFAFMessage();
        authenticationResponse.setHeader(operationHeader);

        if (!appname.isEmpty()) {
            Extension[] extensions = new Extension[1];
            Extension extension = new Extension();
            extension.setId(KEY_APPNAME);
            extension.setData(appname);
            extensions[0] = extension;
            authenticationResponse.setExts(extensions);
        }

        byte[] signedData = new byte[result.getData().length];
        ByteUtils.copy(result.getData(), 0, result.getData().length, signedData, 0);

        IFAFSignedData ifafSignedData = new IFAFSignedData();
        ifafSignedData.setScheme("IFAFV1TLV");
        ifafSignedData.setIdentifyData(Base64.encodeToString(signedData, Base64.URL_SAFE));
        authenticationResponse.setSignedData(ifafSignedData);

        Gson gson = new Gson();
        String authticatorMessage = gson.toJson(authenticationResponse);
        return authticatorMessage;
    }
}
